package com.hydra.framework.router.interceptor;

import android.util.Log;

import com.hydra.framework.router.RouterIntent;

import java.util.HashMap;
import java.util.TreeSet;

import static com.hydra.framework.event.core.EventDispatcher.EVENT_LOG_TAG;

/**
 * Created by Hydra on 2017/8/3.
 *
 */
public class RouterInterceptorList {

    private TreeSet<RouterInterceptor> mInterceptors;
    private HashMap<Integer, RouterInterceptor> mInterceptorMap;

    public RouterInterceptorList() {
        mInterceptors = new TreeSet<>(RouterInterceptor.sRouterInterceptorComparator);
        mInterceptorMap = new HashMap<>();
    }

    public RouterInterceptorList(RouterInterceptorList from) {
        mInterceptors = new TreeSet<>(from.mInterceptors);
        mInterceptorMap = new HashMap<>(from.mInterceptorMap);
    }

    public boolean invokeToInterceptors(RouterIntent eventIntent) {
        RouterInterceptorList copiedInterceptorList;

        synchronized (this) {
            copiedInterceptorList = new RouterInterceptorList(this);
        }

        for (RouterInterceptor receiver : copiedInterceptorList.mInterceptors) {
            if (receiver.intercept(eventIntent)) {
                return true;
            }
        }

        return false;
    }

    public synchronized void add(RouterInterceptor object) {
        boolean preExist = !mInterceptors.add(object);

        mInterceptorMap.put(System.identityHashCode(object.interceptor()), object);

        if(preExist) {
            Log.e(EVENT_LOG_TAG, "add interceptor destination warning, destination already " +
                    "exist : " + object.toString());
        }
    }

    public synchronized void remove(RouterInterceptor object) {
        mInterceptors.remove(object);
        mInterceptorMap.remove(System.identityHashCode(object));
    }

    public synchronized void remove(IRouterInterceptor object) {
        RouterInterceptor routerInterceptor = mInterceptorMap.remove(System.identityHashCode(object));

        if(routerInterceptor != null) {
            mInterceptors.remove(routerInterceptor);
        }
    }

    public synchronized int size() {
        return mInterceptors.size();
    }
}
